package middleware

import (
	"bytes"
	"github.com/e421083458/gin_scaffold/public"
	"github.com/e421083458/golang_common/lib"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"time"
)

// 请求进入日志
func RequestInLog(c *gin.Context) {
	traceContext := lib.NewTrace()
	//尝试从上游获取 traceid  和 spanid 没有就使用新的
	if traceId := c.Request.Header.Get("com-header-rid"); traceId != "" {
		traceContext.TraceId = traceId
	}
	if spanId := c.Request.Header.Get("com-header-spanid"); spanId != "" {
		traceContext.SpanId = spanId
	}

	//记录请求的时间点  记录起来
	c.Set("startExecTime", time.Now())
	//将traceid 设置到gin 的上下文里面
	c.Set("trace", traceContext)

	//获取请求的参数值
	bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
	//将值重新赋值到 request.body  方便后续流程的正常执行
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) // Write body back

	//将值打印到日志中
	lib.Log.TagInfo(traceContext, "_com_request_in", map[string]interface{}{
		"uri":    c.Request.RequestURI,
		"method": c.Request.Method,
		"args":   c.Request.PostForm,
		"body":   string(bodyBytes),
		"from":   c.ClientIP(),
	})
}

// 请求输出日志
func RequestOutLog(c *gin.Context) {
	// after request
	endExecTime := time.Now()
	//获取上下文中的响应值
	response, _ := c.Get("response")
	//获取请求的开始时间
	st, _ := c.Get("startExecTime")
	//计算整个请求的耗时
	startExecTime, _ := st.(time.Time)
	//增加请求退出的日志记录
	public.ComLogNotice(c, "_com_request_out", map[string]interface{}{
		"uri":       c.Request.RequestURI,//请求url
		"method":    c.Request.Method,//请求类型
		"args":      c.Request.PostForm,//post 请求数据
		"from":      c.ClientIP(),//请求ip
		"response":  response,//程序的响应内容
		"proc_time": endExecTime.Sub(startExecTime).Seconds(),//程序执行的时间
	})
}

//通过中间件 串联俩个方法
func RequestLog() gin.HandlerFunc {
	return func(c *gin.Context) {
		RequestInLog(c)
		defer RequestOutLog(c)
		c.Next()
	}
}